import { PlainObjectType } from "./PlainType";

type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type MulKeys<U extends PlainObjectType[], Last = never> = U extends [
	infer P extends PlainObjectType,
	...infer R extends PlainObjectType[]
]
	? MulKeys<R, keyof P | Last>
	: Last;

type WithoutMul<T extends PlainObjectType[], U extends PlainObjectType> = {
	[P in Exclude<MulKeys<T>, keyof U>]?: never;
};
/**返回互斥的两个对象类型 */
export type XOR<T extends PlainObjectType, U extends PlainObjectType> =
	| (Without<T, U> & U)
	| (Without<U, T> & T);

// export type XORTuple<
// 	T extends Array<PlainObjectType>,
// 	Last extends PlainObjectType = {}
// > = T extends []
// 	? Last
// 	: T extends [
// 			infer U extends PlainObjectType,
// 			...infer V extends Array<PlainObjectType>
// 	  ]
// 	? XORTuple<V, XOR<Last, U>>
// 	: never;

export type XORTuple<
	T extends Array<PlainObjectType>,
	LastArr extends Array<PlainObjectType> = [],
	Last = never
> = T extends [
	infer P extends PlainObjectType,
	...infer R extends PlainObjectType[]
]
	? XORTuple<
			R,
			[...LastArr, P],
			(WithoutMul<[...LastArr, ...R], P> & P) | Last
	  >
	: Last;
